import pyglet
import sys,os
import glob
import time
from pyglet.gl import *
from pyglet.window import key,mouse
import pyglet.graphics,ctypes

from framework import *
from widget import *


class STFViewControl(icuControl): #scale-to-fit view mode
    """Controller code for the scale-to-fit mode.
    Receives the raw signal from the mode
    And tells the mode what it specifically needs to do"""

    def on_key_press(self,symbol,modifiers):
        if symbol == key.LEFT: # Back one picture
            self.mode.prevPic()
        elif symbol == key.RIGHT: # Forward one picture
            self.mode.nextPic()
        elif symbol == key.UP: # Go to the parent directory
            self.mode.dirUp()
        elif symbol == key.DOWN: # Choose another directory
            self.mode.chooseDir()
        return False

    def on_mouse_press(self,x,y,button,modifiers):
        if button == mouse.RIGHT:
            self.mode.openPieMenu(x,y)
        return False

    def on_resize(self,width,height):
        self.mode.view.recalc = True
        return False


class BasicVModeView(icuView):
    """Abstract class that defines most of the functionality for
    viewing images in any mode."""
    
    def __init__(self, mode):
        self.closinganim = False
        self.mode = mode
        self.waitoneframe = False
        self.image = None
        self.oldimage = None
        self.recalc = True
        self.setClearColor()

    def update(self,dt): pass

    def draw(self):
        if self.recalc: self.recalcpos()
        self.recalc = False
        self.draw_image()
        if self.waitoneframe: self.waitoneframe = False
        else:
            if self.oldimage:
                self.oldimage.delete()
                self.oldimage = None
            if main.cache[2] is None:
                main.cache[2] = main.loadImage(main.piclist[(main.curIndex+1) % len(main.piclist)])
            elif main.cache[0] is None:
                main.cache[0] = main.loadImage(main.piclist[(main.curIndex-1) % len(main.piclist)])

    #redefine these
    def draw_image(self): self.image.draw()

    def recalcpos(self): #recenter and scale
        w,h = main.winman.window.get_size()
        self.image.scale = 1.0 #to fix image's width/height values (make them actual pixel values)
        self.image.scale = min(w/float(self.image.width),h/float(self.image.height))
        self.image.x = (w - self.image.width)/2
        self.image.y = (h - self.image.height)/2

    def setClearColor(self):
        glClearColor(238/255.,242/255.,251/255.,1.0)


class AbstractVModeCF: #common control functions between view modes (primarily caching)

    def nextPic(self):
        if len(main.piclist) > 0 and not self.view.oldimage:
            main.curIndex = (main.curIndex + 1) % len(main.piclist)
            if len(main.piclist) > 3:
                # Have to shift the cache to the left
                main.cache[0] = main.cache[1]
                main.cache[1] = main.cache[2]
                main.cache[2] = None
                self.view.waitoneframe = True
                self.view.oldimage = self.view.image
                #main.cache[2] = main.loadImage(main.piclist[(main.curIndex+1) % len(main.piclist)])
                self.view.image = pyglet.sprite.Sprite(main.cache[1])
            elif len(main.piclist) == 2:
                main.curCacheIndex = main.curCacheIndex ^ 1
                self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            elif len(main.piclist) == 1: pass
            else:
                # Small directory, don't need to adjust cache contents at all
                # Just change the cache index
                main.curCacheIndex = (main.curCacheIndex + 1) % len(main.cache)
                self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.curzoom = 1
            self.view.recalc = True
            self.updateCaption()
    
    def prevPic(self):
        if len(main.piclist) > 0 and not self.view.oldimage:
            main.curIndex = (main.curIndex - 1) % len(main.piclist)
            if len(main.piclist) > 3:
                # Have to shift the cache to the right
                main.cache[2] = main.cache[1]
                main.cache[1] = main.cache[0]
                main.cache[0] = None
                self.view.waitoneframe = True
                self.view.oldimage = self.view.image
                #main.cache[0] = main.loadImage(main.piclist[(main.curIndex-1) % len(main.piclist)])
                self.view.image = pyglet.sprite.Sprite(main.cache[1])
            elif len(main.piclist) == 2:
                main.curCacheIndex = main.curCacheIndex ^ 1
                self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            elif len(main.piclist) == 1: pass
            else:
                # Small directory, don't need to adjust cache contents at all
                # Just change the cache index
                main.curCacheIndex = (main.curCacheIndex - 1) % len(main.cache)
                self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.curzoom = 1
            self.view.recalc = True
            self.updateCaption()
    
    def dirUp(self):
        main.loadDir(os.path.dirname(main.curdir))
        if len(main.piclist) == 0:
            self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
        else:
            self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.updateCaption()
        self.view.recalc = True

    def chooseDir(self):
        option = main.findFile()
        main.winman.window.activate()
        if option:
            main.loadDir(option)
            if len(main.piclist) == 0:
                self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
            else:
                self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
                self.updateCaption()
            self.view.recalc = True

    def updateCaption(self): #update the caption to reflect the new image
        d,f = os.path.split(main.piclist[main.curIndex])
        main.winman.window.set_caption(os.path.basename(d)+'/'+f)

    def destroy(self): #clean up sprite memory
        if self.view.oldimage: self.view.oldimage.delete()
        self.view.image.delete()


class STFViewMode(icuMode,AbstractVModeCF):
    """Actual class referred to by the main object.
    Takes in event signals and relays information to view, control and main"""

    def __init__(self):
        self.control = STFViewControl(self)
        self.view = BasicVModeView(self)
        if len(main.piclist) == 0:
            self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
        else:
            self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.updateCaption()
        self.curzoom = 1 #to support caching fcns

    def upperlayer(self): return False

    def openPieMenu(self,x,y):
        main.mode.append(ViewPieMode(x,y,ViewPieMode.SCALE_TO_FIT_MODE))


class ZoomViewControl(icuControl):
    """Controller class for the zoom view mode"""

    def on_key_press(self, symbol, modifiers):
        if symbol == key.LEFT:
            self.mode.prevPic()
        elif symbol == key.RIGHT:
            self.mode.nextPic()
        elif symbol == key.UP:
            self.mode.dirUp()
        elif symbol == key.DOWN:
            self.mode.chooseDir()
        elif symbol == key.EQUAL and (modifiers & key.MOD_CTRL): # Zoom in
            self.mode.zoom(1)
        elif symbol == key.MINUS and (modifiers & key.MOD_CTRL): # Zoom out
            self.mode.zoom(-1)
        return False

    def on_mouse_press(self,x,y,button,modifiers):
        if button == mouse.RIGHT:
            self.mode.openPieMenu(x,y)

    def on_mouse_drag(self,x,y,dx,dy,button,modifiers):
        if button == mouse.LEFT: # Panning the image (when relevant)
            self.mode.pan(dx,dy)

    def on_mouse_scroll(self,x,y,scroll_x,scroll_y):
        self.mode.zoom(scroll_y/abs(scroll_y),x,y)

    def on_resize(self, width, height):
        self.mode.view.recalc = True
        return False


class ZoomVModeView(BasicVModeView):
    """Display manager for zoom view mode.
    Needs to manage the position of the image on the window so its movement is
    restricted to the window's dimensions"""

    def recalcpos(self): #recenter, but don't re-scale
        w,h = main.winman.window.get_size()
        iw = self.image.width; ih = self.image.height
        ix = self.image.x; iy = self.image.y
        if iw <= w: self.image.x = (w-iw)//2 #if window is larger, center
        elif ix > 0: self.image.x = 0 #if window is smaller, limit picture to it (no black borders)
        elif ix+iw < w: self.image.x += w-(ix+iw)
        if ih <= h: self.image.y = (h-ih)//2
        elif iy > 0: self.image.y = 0
        elif iy+ih < h: self.image.y += h-(iy+ih)

    def setClearColor(self):
        glClearColor(238/255.,242/255.,251/255.,1.0)


class ZoomViewMode(icuMode,AbstractVModeCF):
    """Public zoom mode interface"""
    
    def __init__(self):
        self.control = ZoomViewControl(self)
        self.view = ZoomVModeView(self)
        if len(main.piclist) == 0:
            self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
        else:
            self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.updateCaption()
        self.curzoom = 1

    def upperlayer(self): return False

    def pan(self,dx,dy):
        self.view.image.x += dx
        self.view.image.y += dy
        self.view.recalc = True

    def zoom(self,zdir,mx=None,my=None):
        #positive curzoom is multiples (out), negative curzoom is fractions (in)
        self.curzoom *= 1 + zdir * 0.1
        newscale = self.curzoom

        #determine zoom-in/out point and adjust final position accordingly
        w,h = main.winman.window.get_size()
        ix = self.view.image.x; iy = self.view.image.y
        if mx == None: mx = w//2
        if my == None: my = h//2
        sprop = self.view.image.scale; sprop = ((newscale-sprop)/sprop)
        self.view.image.x -= sprop*(mx-ix)
        self.view.image.y -= sprop*(my-iy)
        self.view.image.scale = newscale
        self.view.recalc = True

    def openPieMenu(self,x,y):
        main.mode.append(ViewPieMode(x,y,ViewPieMode.ZOOM_MODE))


class PixelVModeView(ZoomVModeView):

    TRANSPARENCYMASK = (GLubyte * 128)(0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF,
                                       0x00,0xFF,0x00,0xFF,0x00,0xFF,0x00,0xFF)

    def draw_image(self):
        w,h = main.winman.window.get_size()
        glEnable(GL_POLYGON_STIPPLE)
        glPolygonStipple(self.__class__.TRANSPARENCYMASK)
        glColor4ub(204,204,204,255)
        glRectf(0,0,w,h)
        #pyglet.graphics.draw(4,GL_QUADS,('v2f',(0,h,w,h,w,0,0,0)),('c4B',(215,215,215,255)*4))
        glDisable(GL_POLYGON_STIPPLE)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
        self.image.draw() #right now, this will break on the large image
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)

    def setClearColor(self):
        glClearColor(1.0,1.0,1.0,1.0)


class PixelViewMode(ZoomViewMode):
    
    def __init__(self):
        self.control = ZoomViewControl(self)
        self.view = PixelVModeView(self)
        if len(main.piclist) == 0:
            self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
        else:
            self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.updateCaption()
        self.curzoom = 1

    def zoom(self,zdir,mx=None,my=None):
        #positive curzoom is multiples (out), negative curzoom is fractions (in)
        self.curzoom += zdir
        if self.curzoom == 0: self.curzoom += 2*zdir
        if self.curzoom > 0: newscale = float(self.curzoom)
        else: newscale = -1.0/self.curzoom

        #determine zoom-in/out point and adjust final position accordingly
        w,h = main.winman.window.get_size()
        ix = self.view.image.x; iy = self.view.image.y
        if mx == None: mx = w//2
        if my == None: my = h//2
        sprop = self.view.image.scale; sprop = ((newscale-sprop)/sprop)
        self.view.image.x -= sprop*(mx-ix)
        self.view.image.y -= sprop*(my-iy)
        self.view.image.scale = newscale
        self.view.recalc = True

    def openPieMenu(self,x,y):
        main.mode.append(ViewPieMode(x,y,ViewPieMode.PIXEL_MODE))


class SlideshowControl(icuControl):

    def on_key_press(self,symbol,modifiers):
        self.mode.switchback()
        return False

    def on_mouse_press(self,x,y,button,modifiers):
        self.mode.switchback()
        return False

    def on_resize(self,width,height):
        self.mode.view.recalc = True
        return False


class SlideshowMode(STFViewMode):

    def __init__(self):
        self.control = SlideshowControl(self)
        self.view = BasicVModeView(self)
        if len(main.piclist) == 0:
            self.view.image = pyglet.sprite.Sprite(pyglet.image.load("NoImages.png"))
        else:
            self.view.image = pyglet.sprite.Sprite(main.cache[main.curCacheIndex])
            self.updateCaption()
            main.winman.window.set_caption("---SLIDESHOW--- "+main.winman.window.caption)
        self.curzoom = 1 #to support caching fcns
        self.stime = self.ctime = time.time()

    def upperlayer(self): return False

    def update(self,dt):
        if len(main.piclist):
            self.ctime = time.time()
            if self.ctime - self.stime > 5: #every five seconds, change the image
                self.stime = self.ctime
                self.nextPic()
                main.winman.window.set_caption("---SLIDESHOW--- "+main.winman.window.caption)
            self.view.update(dt)

    def draw(self):
        self.view.draw()
        w,h = main.winman.window.get_size()
        upperh = (h-14)*((self.ctime-self.stime)/5)+7
        pyglet.graphics.draw(4,GL_QUADS,('v2f',(w-13,7,w-13,upperh,w-6,upperh,w-6,7)),('c4B',(0,0,0,255)*4))
        pyglet.graphics.draw(4,GL_LINE_LOOP,('v2f',(w-14,6,w-14,upperh,w-6,upperh,w-6,6)),('c4B',(255,255,255,255)*4))
        pyglet.graphics.draw(4,GL_LINE_LOOP,('v2f',(w-15,5,w-15,h-5,w-5,h-5,w-5,5)),('c4B',(0,0,0,255)*4))

    def switchback(self): #change back to scale-to-fit mode
        main.mode[-1] = STFViewMode()
        self.destroy()


import modeedit


class ViewPieControl(icuControlUL):

    def on_mouse_press(self,x,y,button,modifiers):
        if button == mouse.LEFT:
            if not self.mode.hitEnter(x,y): self.mode.close()
        if button == mouse.RIGHT:
            self.mode.close()
        return False

    def on_mouse_drag(self,x,y,dx,dy,button,modifiers):
        if button == mouse.LEFT:
            self.mode.hitDrag(x,y,dx,dy)

    def on_mouse_release(self,x,y,button,modifiers):
        if button == mouse.LEFT:
            self.mode.hitExit(x,y)

    def on_resize(self,width,height):
        self.mode.view.recalc = True
        return True

class ViewPieView(icuView):

    def __init__(self,mode):
        self.closinganim = False
        self.mode = mode
        self.sprite = []
        self.rootnode = None
        self.bkgvar = Var(0.0,0.0,1.0)
        self.recalc = False
        self.ttwid = None

    def update(self,dt):
        if self.recalc: self.recalcpos()
        self.recalc = False
        for spr in self.sprite: spr.update(dt)
        if self.rootnode: self.rootnode.update(dt)
        if self.closinganim and not self.rootnode.sanim.active():
            for spr in self.sprite: spr.delete()
            self.rootnode.deletehierarchy()
            main.mode.pop()
        self.bkgvar.update(dt)
        ttwid = self.rootnode.gethitobj(*main.mpos)
        if ttwid and ttwid == self.ttwid:
            main.tooltip.create(dt,ttwid,*main.mpos)
        else:
            main.tooltip.kill(dt)
            self.ttwid = ttwid

    def draw(self):
        w,h = main.winman.window.get_size()
        bkgprop = self.bkgvar()
        glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
        pyglet.graphics.draw(4,GL_QUADS,('v2f',(0,h,w,h,w,0,0,0)),('c4B',(0,0,0,int(196*bkgprop))*2+(0,0,0,int(128*bkgprop))*2))
        glDisable(GL_BLEND)
        for spr in self.sprite: spr.draw()
        if self.rootnode: self.rootnode.draw()

    def recalcpos(self):
        w,h = main.winman.window.get_size()
        sx = self.rootnode.sprite.x; sy = self.rootnode.sprite.y
        dx = dy = 0
        pushamt = 105 #pixels
        if sx < pushamt: dx = pushamt-sx
        elif sx > w-pushamt: dx = w-pushamt-sx
        if sy < pushamt: dy = pushamt-sy
        elif sy > h-pushamt: dy = h-pushamt-sy
        self.rootnode.selected = True
        self.rootnode.hitdrag(sx+dx,sy+dy,dx,dy)
        self.rootnode.selected = False
        


class ViewPieMode(icuMode):

    SCALE_TO_FIT_MODE = 1
    ZOOM_MODE = 2
    PIXEL_MODE = 3
    SLIDESHOW_MODE = 4 #we may not have a right-click menu on slideshow mode, but might as well have the constant defined
    images = None

    def __init__(self,x,y,opener):
        self.closinganim = False
        self.view = ViewPieView(self)
        self.control = ViewPieControl(self)
        w,h = main.winman.window.get_size()
        if self.__class__.images == None: #self.__class__.images is more formal, and I like to use it when caching images
            self.__class__.images = [pyglet.image.load("ScaleToFitMode.png"), #Scale-to-fit mode (yellow)
                                     pyglet.image.load("ZoomMode.png"), #Zoom mode (orange)
                                     pyglet.image.load("PixelMode.png"), #Pixel mode (red)
                                     pyglet.image.load("SlideshowMode.png"), #Slideshow mode (purple)
                                     pyglet.image.load("View_GoUp.png"), #Go up a folder (light teal)
                                     pyglet.image.load("View_GoInto.png"), #Go into a folder (dark teal)
                                     pyglet.image.load("View_Refresh.png"), #Refresh widget (light green)
                                     pyglet.image.load("EditMode.png"), #Edit mode (green)
                                     pyglet.image.load("View_Zoom.png"), #Zoom widget (dark blue)
                                     pyglet.image.load("SmallOrb.png")] #Zoom orbiter (light blue)
            for img in self.__class__.images: #center the anchor point (defaults to BL corner)
                img.anchor_x = img.width/2
                img.anchor_y = img.height/2

        anglect = 8
        removeedit = (not main.piclist) or isinstance(main.mode[-1].view.image.image,pyglet.image.Animation)
        if opener == self.SCALE_TO_FIT_MODE: anglect -= 1
        if removeedit: anglect -= 1
        angleamt = 360./anglect
        if opener == self.SCALE_TO_FIT_MODE: #set up the center and three other view modes depending on current mode.
            centerspr = pyglet.sprite.Sprite(self.images[0],x,y)
            centerspr.opacity = 0
            centerspr.scale = 80/50.
            centerspr.color = (128,128,128)
            widroot = Widget(centerspr,40,"Scale to fit mode",116)
            wid1 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[1]),25,"Zoom mode",80,self.changeViewMode,[ZoomViewMode]),0,0)
            wid2 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[2]),25,"Pixel mode",75,self.changeViewMode,[PixelViewMode]),angleamt,0)
            wid3 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[3]),25,"Slideshow mode",110,self.changeViewMode,[SlideshowMode]),angleamt*2,0)
        elif opener == self.ZOOM_MODE: #set up the center and three other view modes depending on current mode.
            centerspr = pyglet.sprite.Sprite(self.images[1],x,y)
            centerspr.opacity = 0
            centerspr.scale = 80/50.
            centerspr.color = (128,128,128)
            widroot = Widget(centerspr,40,"Zoom mode",80)
            wid1 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[0]),25,"Scale to fit mode",116,self.changeViewMode,[STFViewMode]),0,0)
            wid2 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[2]),25,"Pixel mode",75,self.changeViewMode,[PixelViewMode]),angleamt,0)
            wid3 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[3]),25,"Slideshow mode",110,self.changeViewMode,[SlideshowMode]),angleamt*2,0)
        elif opener == self.PIXEL_MODE: #set up the center and three other view modes depending on current mode.
            centerspr = pyglet.sprite.Sprite(self.images[2],x,y)
            centerspr.opacity = 0
            centerspr.scale = 80/50.
            centerspr.color = (128,128,128)
            widroot = Widget(centerspr,40,"Pixel mode",75)
            wid1 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[0]),25,"Scale to fit mode",116,self.changeViewMode,[STFViewMode]),0,0)
            wid2 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[1]),25,"Zoom mode",80,self.changeViewMode,[ZoomViewMode]),angleamt,0)
            wid3 = widroot.attach(FuncWidget(pyglet.sprite.Sprite(self.images[3]),25,"Slideshow mode",110,self.changeViewMode,[SlideshowMode]),angleamt*2,0)

        wid1.sprite.opacity = 0; wid1.sanim.aalpha.offset = 0
        wid2.sprite.opacity = 0; wid2.sanim.aalpha.offset = 0
        wid3.sprite.opacity = 0; wid3.sanim.aalpha.offset = 0

        widroot.sanim.fadein([0.5]) #smoothly fade in center in half a second
        #move out from center in half a second fading in in 0.3s after 0.2s delay
        wid1.sanim.fadein([0.3],[],[0.2]); wid1.length.add([0.5],80,2)
        wid2.sanim.fadein([0.3],[],[0.2]); wid2.length.add([0.5],80,2)
        wid3.sanim.fadein([0.3],[],[0.2]); wid3.length.add([0.5],80,2)

        #force the full menu to be visible, regardless of right-clicked point, by smoothly moving the hierarchy into the screen
        pushamt = 105 #pixels
        widroot.sanim.ax.movto([0.5],max(pushamt,min(x,w-pushamt)),2)
        widroot.sanim.ay.movto([0.5],max(pushamt,min(y,h-pushamt)),2)

        vmode = [[STFViewMode,ZoomViewMode,PixelViewMode][opener-1]]
        fcnlist = [["Go up",43,self.upDir],
                   ["Enter subdir",84,self.chooseDir],
                   ["Refresh",55,self.refresh,vmode],
                   ["Edit mode",69,self.changeEditMode,vmode]]
        for i in xrange(4,removeedit and 7 or 8):
            newsprite = pyglet.sprite.Sprite(self.images[i])
            newsprite.opacity = 0
            newwid = widroot.attach(FuncWidget(newsprite,25,*fcnlist[i-4]),angleamt*(i-1),0)
            newwid.sanim.fadein([0.3],[],[0.2])
            newwid.length.add([0.5],80,2)

        if not opener == self.SCALE_TO_FIT_MODE: #add zoom button
            newsprite = pyglet.sprite.Sprite(self.images[8])
            newsprite.opacity = 0
            newwid = widroot.attach(FuncWidget(newsprite,25,"Actual size",75,self.zoomReset),angleamt*(anglect-1),0)
            newwid.sanim.fadein([0.3],[],[0.2])
            newwid.length.add([0.5],80,2)
            self.startzoom = main.mode[-1].curzoom
            newsprite = pyglet.sprite.Sprite(self.images[9])
            newsprite.opacity = 0
            newwid = newwid.attach(RotateWidget(newsprite,10,"Zoom (CCW+,CW-)",131,self.changeZoom),-90,0)
            newwid.sanim.fadein([0.3],[],[0.2])
            newwid.angle.add([0.3],90,2,[],[0.2])
            newwid.length.add([0.3],35,2,[],[0.2])

        self.view.rootnode = widroot
        self.view.bkgvar.add([0.5],1.0)

    def hitEnter(self,x,y): return self.view.rootnode.hitenter(x,y)

    def hitExit(self,x,y): return self.view.rootnode.hitexit(x,y)

    def hitDrag(self,x,y,dx,dy):
        w,h = main.winman.window.get_size()
        sx = self.view.rootnode.sprite.x; sy = self.view.rootnode.sprite.y
        pushamt = 105 #pixels
        if sx+dx < pushamt: dx = pushamt-sx
        elif sx+dx > w-pushamt: dx = w-pushamt-sx
        if sy+dy < pushamt: dy = pushamt-sy
        elif sy+dy > h-pushamt: dy = h-pushamt-sy
        return self.view.rootnode.hitdrag(x,y,dx,dy)

    def close(self):
        widroot = self.view.rootnode
        widroot.sanim.fadeout([0.3])
        for wid in widroot.child:
            wid.sanim.fadeout([0.3])
            wid.length.add([0.3],40,2)
        self.view.closinganim = True
        self.view.bkgvar.add([0.3],-1.0)
        main.tooltip.kill(1.0)

    def changeViewMode(self,wcall,newmode):
        main.mode[-2].destroy()
        main.mode[-2] = newmode()
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def changeEditMode(self,wcall,oldm):
        oldmode = main.mode[-2]
        oldmode.destroy()
        main.mode[-2] = modeedit.EditMode(oldm)
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def upDir(self,wcall):
        main.mode[-2].dirUp()
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def chooseDir(self,wcall):
        main.mode[-2].chooseDir()
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def refresh(self,wcall,oldm):
        oldmode = main.mode[-2]
        oldmode.destroy()
        main.loadDir(main.curdir)
        main.mode[-2] = oldm()
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def zoomReset(self,wcall):
        main.mode[-2].curzoom = 1
        main.mode[-2].view.image.scale = 1.0
        main.mode[-2].view.recalc = True
        self.close()
        wcall.length.cut()
        wcall.length.add([0.3],-40,2)

    def changeZoom(self,amt):
        if amt % 360: main.mode[-2].zoom(amt/abs(amt))
            

    def defaultfcn(self,callingwidget):
        print "Clicked",callingwidget
        self.close()
        callingwidget.length.cut()
        callingwidget.length.add([0.3],-40,2)


if __name__ == "__main__":
    main.mode.append(PixelViewMode())
    #main.mode.append(ZoomViewMode())
    #main.mode.append(STFViewMode())
    #pyglet.clock.schedule_interval(main.on_draw,1/60.0)
    pyglet.app.run()
